﻿Imports System.Collections.Specialized

Imports System.IO
Imports System.Globalization
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports System.Collections.ObjectModel
Imports System
Imports System.ComponentModel
Imports System.Xml.Serialization
Imports System.Threading
Imports Hinshelwood.TFSHeatITSM.TeamFoundationExtensions
Imports QuantumBitDesigns.Core
Imports Infragistics.Windows.Ribbon

Namespace Controlers

    Public Class TeamSystemControler(Of TView As {UIElement, ITeamSystemView(Of TView)})
        Inherits ControlerBase(Of TView)



        Public Sub New(ByVal View As TView)
            MyBase.New(View)
        End Sub

        Protected Overrides Sub Initilise()

        End Sub

        Protected Overrides Sub InitiliseObjects()
            m_AvailableServers = New ObservableList(Of TeamFoundationServer)(View.Dispatcher)
            m_AvailableProjects = New ObservableList(Of Project)(View.Dispatcher)
            m_AvailableWorkItems = New ObservableList(Of WorkItem)(View.Dispatcher)
        End Sub

        Protected Overrides Sub InitiliseLoad()
            System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf LoadSelectableTeamServers_Async))
        End Sub

        Protected Overrides Sub InitiliseNavigation()
            'Dim r As XamRibbon = View.GetNavigation
            'Dim serverComboEditorTool As New ComboEditorTool
            'serverComboEditorTool.DataContext = Me
            'serverComboEditorTool.Id = "uxTeamAvailableServers2"
            'serverComboEditorTool.Name = "uxTeamAvailableServers2"
            'serverComboEditorTool.DropDownResizeMode = Infragistics.Windows.Controls.PopupResizeMode.VerticalOnly
            'serverComboEditorTool.IsEditable = False
            'serverComboEditorTool.EditAreaWidth = 148.0
            'serverComboEditorTool.SetBinding(Infragistics.Windows.Editors.XamComboEditor.SelectedItemProperty, "SelectedServer")
            'serverComboEditorTool.SetBinding(Infragistics.Windows.Editors.XamComboEditor.ItemsSourceProperty, "AvailableServers")
            ''serverComboEditorTool.SelectedItem = "{Binding SelectedServer}"
            ''serverComboEditorTool.ItemsSource = "{Binding AvailableServers}"
            'NavigationRibbonGroup("Home", "Team System").Items.Add(serverComboEditorTool)


            'Dim x As New RibbonTabItem
            'x.
        End Sub

        Protected Overrides Sub DisposeManagedObjects()
            m_AvailableServers = Nothing
            m_AvailableProjects = Nothing
            m_AvailableWorkItems = Nothing
        End Sub

        Protected Overrides Sub DisposeUnmanagedObjects()

        End Sub

        Public Overrides Sub Reset()


        End Sub


#Region " Team Server "
        Private m_AvailableServers As ObservableList(Of TeamFoundationServer)
        Private m_SelectedServer As TeamFoundationServer = Nothing
        Private Shared m_HasSelectedServer As Boolean = False

        Public Property SelectedServer() As TeamFoundationServer
            Get
                Return m_SelectedServer
            End Get
            Set(ByVal value As TeamFoundationServer)
                If m_SelectedServer Is Nothing OrElse Not value.Name = m_SelectedServer.Name Then
                    If value Is Nothing Then
                        m_SelectedServer = Nothing
                        My.Settings.SelectedTeamServer = ""
                        OnPropertyChanged("SelectedServer")
                        HasSelectedServer = True
                        Exit Property
                    End If
                    If value.HasAuthenticated Then
                        m_SelectedServer = value
                        My.Settings.SelectedTeamServer = value.Uri.ToString
                        OnPropertyChanged("SelectedServer")
                        HasSelectedServer = True
                    Else
                        Dim x As New Action(Of TeamFoundationServer)(AddressOf AuthenticateSelectedServer_Async)
                        x.BeginInvoke(value, Nothing, Nothing)
                    End If
                End If
            End Set
        End Property

        Public Sub LoadSelectableTeamServers_Async()
            For Each teamServer In Microsoft.TeamFoundation.Client.RegisteredServers.GetServers
                Dim linkedTeamServer As New TeamFoundationServer(teamServer.Name, View.GetCredentialProvider)
                If Not m_AvailableServers.Contains(linkedTeamServer) Then
                    m_AvailableServers.Add(linkedTeamServer)
                    If linkedTeamServer.Uri.ToString = My.Settings.SelectedTeamServer Then
                        SelectedServer = linkedTeamServer
                    End If
                End If
            Next
        End Sub

        Private Sub AuthenticateSelectedServer_Async(ByVal TeamServer As TeamFoundationServer)
            TeamServer.Authenticate()
            If TeamServer.HasAuthenticated Then
                SelectedServer = TeamServer
                LoadSelectableTeamProjects_Async()
            Else
                SelectedServer = Nothing
            End If
        End Sub

        Public Property HasSelectedServer() As Boolean
            Get
                Return m_HasSelectedServer
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedServer Then
                    m_HasSelectedServer = value
                    OnPropertyChanged("HasSelectedServer")
                End If
            End Set
        End Property

        Public ReadOnly Property WorkItemStore() As WorkItemStore
            Get
                ' Could be speeded up by caching the Work item store in a doctionary
                If Not SelectedServer Is Nothing Then
                    Return DirectCast(SelectedServer.GetService(GetType(WorkItemStore)), WorkItemStore)
                End If
                Return Nothing
            End Get
        End Property

        Public ReadOnly Property AvailableServers() As ObservableCollection(Of TeamFoundationServer)
            Get
                Return m_AvailableServers.ObservableCollection
            End Get
        End Property

#End Region

#Region "Team Project"

        Private m_SelectedProject As Project = Nothing
        Private m_AvailableProjects As ObservableList(Of Project)
        Private m_HasSelectedProject As Boolean = False

        Public Property SelectedProject() As Project
            Get
                Return m_SelectedProject
            End Get
            Set(ByVal value As Project)
                If m_SelectedProject Is Nothing OrElse Not value.Name = m_SelectedProject.Name Then
                    m_SelectedProject = value
                    If value Is Nothing Then
                        My.Settings.SelectedTeamProject = ""
                    Else
                        My.Settings.SelectedTeamProject = value.Name
                    End If
                    ' My.Settings.Save()
                    OnPropertyChanged("SelectedProject")
                    HasSelectedProject = Not m_SelectedProject Is Nothing
                    System.Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf LoadItemsAvailable_Async))
                End If
            End Set
        End Property

        Public ReadOnly Property AvailableProjects() As ObservableCollection(Of Project)
            Get
                Return m_AvailableProjects.ObservableCollection
            End Get
        End Property

        Public Property HasSelectedProject() As Boolean
            Get
                Return m_HasSelectedProject
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedProject Then
                    m_HasSelectedProject = value
                    OnPropertyChanged("HasSelectedProject")
                End If
            End Set
        End Property

        Public Sub LoadSelectableTeamProjects_Async()
            For Each project In WorkItemStore.Projects
                If Not m_AvailableProjects.Contains(project) Then
                    m_AvailableProjects.Add(project)
                    If project.Name = My.Settings.SelectedTeamProject Then
                        SelectedProject = project
                    End If
                End If
            Next
        End Sub

#End Region

#Region " Work Items "

        Friend m_AvailableWorkItems As ObservableList(Of WorkItem)

        Public ReadOnly Property AvailableWorkItems() As ObservableCollection(Of WorkItem)
            Get
                Return m_AvailableWorkItems.ObservableCollection
            End Get
        End Property

        Public Sub LoadItemsAvailable_Async()
            Dim query As New System.Text.StringBuilder
            query.AppendFormat("SELECT [System.Id] FROM WorkItems WHERE {0} = '{1}' and [System.State] <> 'Closed' ORDER BY [System.Id]", "[System.TeamProject]", SelectedProject.Name)
            Dim wilist As New List(Of WorkItem)
            Try
                Dim wit As WorkItem = Nothing
                SyncLock WorkItemStore
                    Dim cx As WorkItemCollection = WorkItemStore.Query(query.ToString)
                    m_AvailableWorkItems.Clear()
                    For Each WorkItem In cx
                        'm_AvailableWorkItems.Add(WorkItemStore.GetWorkItem(WorkItem.Id))
                        m_AvailableWorkItems.Add(WorkItem)
                    Next
                End SyncLock
                Me.State = ControlerStates.Ready
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Sub



#End Region

        Private Sub CreateWorkItem()
            'Dim WorkItemType As WorkItemType = e.Parameter
            'If Not WorkItemType Is Nothing Then
            '    If TeamSystemControler.CheckWorkItemField(WorkItemType) Then
            '        'MsgBox("Now save work item.")
            '        Dim wi As WorkItem = WorkItemType.NewWorkItem
            '        wi.Title = String.Format("{0} {1} {2} from Heat {3}", LinksControler.SelectedItem.CallLog.Application, LinksControler.SelectedItem.CallLog.CallType, LinksControler.SelectedItem.CallLog.TypeOfCall, LinksControler.SelectedItem.CallLog.CallID)
            '        wi.Description = String.Format(LinksControler.SelectedItem.CallLog.CallDesc)
            '        TeamSystemControler.GetWorkItemField(wi, "HeatITSM.Ref").Value = CInt(LinksControler.SelectedItem.CallLog.CallID)
            '        ' Start Work Item Type Selection
            '        Dim command As ICommand = Controlers.TeamSystemCommands.CreateWorkItemCommand
            '        command.Execute(wi)
            '    Else
            '        MsgBox(String.Format("You will need to add the 'HeatITSM.RefNo' field to your '{0}' on project '{1}'. Use the help menu to access the documentation.", WorkItemType.Name, TeamSystemControler.SelectedProject.Name))
            '    End If
            'End If
        End Sub

        Public Function GetWorkItem(ByVal field As String, ByVal value As String) As WorkItem
            Dim query As New System.Text.StringBuilder
            query.AppendFormat("SELECT [System.Id], [System.Title] FROM WorkItems WHERE [{0}] = '{1}' ORDER BY [System.Id]", field, value)
            Try
                Dim wit As WorkItem = Nothing
                SyncLock WorkItemStore
                    Dim cx As WorkItemCollection = WorkItemStore.Query(query.ToString)
                    If Not cx Is Nothing AndAlso cx.Count > 0 Then
                        wit = WorkItemStore.GetWorkItem(cx(0).Id)
                    End If
                End SyncLock
                If Not wit Is Nothing Then
                    Return wit
                End If
            Catch ex As Exception
                Return Nothing
            End Try
            Return Nothing
        End Function


        Public Function LoadWorkItem(ByVal witid As Integer) As WorkItem
            Return WorkItemStore.GetWorkItem(witid)
        End Function

        Public  Function CheckServerField() As Boolean
            Dim v = (From fd As FieldDefinition In WorkItemStore.FieldDefinitions Where fd.ReferenceName = TeamHelpers.HeatReferenceName).SingleOrDefault
            Return Not (v Is Nothing)
        End Function

        Protected Overrides Sub RecalculateState()

        End Sub

        Protected Overrides Sub PropertyHasChanged(ByVal PropertyName As String)

        End Sub


    End Class

End Namespace